﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Think.Data;
using Think.Extend;

namespace Think.Model
{
    /// <summary>
    /// 实体基类
    /// </summary>
    public class EntityBase
    {
        /// <summary>
        /// 编号[主键]
        /// </summary>
        public int ID { get; set; }
        /// <summary>
        /// 数据项状态
        /// </summary>
        public string DbStatus { get; set; }

        #region 方法
        
        /// <summary>
        /// 取属性值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public object GetProperty(string name)
        {
            return this.GetType().Wrap().GetProperty(name).DynInvoke(this);
        }
        /// <summary>
        /// 取值
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public object GetValue(string name)
        {
            return this.GetType().Wrap().GetProperty(name).DynInvoke(this);
        }
        /// <summary>
        /// 设置属性值
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void SetProperty(string name, object value)
        {
            this.GetType().Wrap().GetProperty(name).DynInvoke(this, value);
        }
        /// <summary>
        /// 取数据
        /// </summary>
        /// <returns></returns>
        public virtual dynamic GetData()
        {
            dynamic o = new ExpandoObject();
            var dic = (IDictionary<string, object>)(o);
            var info = this.GetType().Wrap();
            var mems = info.AllMembers.Where(c => c.MemberType == MemberTypes.Property);
            foreach (var p in mems)
            {
                dic[p.Name] = p.DynInvoke(this);
            }
            return o;
        }
        /// <summary>
        /// 填充
        /// </summary>
        /// <param name="obj"></param>
        public virtual void FillData(object obj)
        {
            var ct = obj.GetType().Wrap();
            if (ct.IsEnumrable)
            {
                var co = obj as IDictionary<string, object>;
                foreach (var kv in co)
                {
                    ct.GetProperty(kv.Key).DynInvoke(this, kv.Value);
                }
            }
            else
            {
                var pis = obj.GetType().GetProperties().Join(
                 this.GetType().GetProperties(),
                 (p) => p.Name,
                 (p) => p.Name,
                 (a, b) => b
                 );
                foreach (var p in pis)
                {
                    var ov = obj.GetType().GetProperty(p.Name).DynInvoke(obj);
                    p.DynInvoke(this, ov);
                }
            }
        }

        #endregion

    }
}
